package com.zjzaki.thingsboard.activity.bluetooth;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;


import androidx.annotation.Nullable;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;


import com.zjzaki.thingsboard.R;
import com.zjzaki.thingsboard.common.GlobalDef;
import com.zjzaki.thingsboard.util.StringUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

public class DeviceBluetoothInfoActivity extends AppCompatActivity {

    /**
     * 提示信息
     */
    private String TAG = DeviceBluetoothInfoActivity.class.getSimpleName();
    /**
     * 标题栏
     */
    private Toolbar toolbar;
    /**
     * 顶部动作栏
     */
    private ActionBar supportActionBar;
    /**
     * 蓝牙设备
     */
    private BluetoothDevice mCurDevice = null;
    /**
     * 蓝牙socket线程
     */
    private DeviceBluetoothInfoActivity.SocketThread mThread = null;
    /**
     * socket信息展示
     */
    private TextView txt_msg_bluetooth;
    /**
     * 设备MAC地址
     */
    private TextView txt_device_bluetooth_info_mac;
    /**
     * 应用程序环境的全局信息的接口
     */
    private Context mContext = this;
    /**
     * 发送的数据类型-字符型
     */
    public static final int DATATYPE_STR = 0;
    /**
     * 发送的数据类型-16进制
     */
    public static final int DATATYPE_HEX = 1;
    /**
     * 总开关
     */
    private Switch mainSwitch;

    /**
     * 页面创建的方法，在页面创建时执行
     * @param savedInstanceState 从String键到各种Parcelable值的映射。
     */
    @SuppressLint("MissingPermission")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.device_bluetooth_info_view);

        toolbar = findViewById(R.id.toolbar_bluetooth);
        txt_device_bluetooth_info_mac = findViewById(R.id.txt_device_bluetooth_info_mac);
        txt_msg_bluetooth = findViewById(R.id.txt_msg_bluetooth);

        //设置标题栏
        setSupportActionBar(toolbar);
        supportActionBar = getSupportActionBar();
        //设置返回键可见
        supportActionBar.setDisplayHomeAsUpEnabled(true);
        //得到当前选中的蓝牙设备
        this.mCurDevice = getIntent().getParcelableExtra("mCurDevice");
        //设置标题栏的名字
        supportActionBar.setTitle(mCurDevice.getName());
        //设置设备MAC
        txt_device_bluetooth_info_mac.setText("设备MAC：" + mCurDevice.getAddress());
        //总开关
        mainSwitch = findViewById(R.id.swi_main_bluetooth);
        //设置事件监听
        mainSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    sendData("{ \"mainSwitch\": 1 }", DATATYPE_STR);
                    mainSwitch.setChecked(true);
                } else {
                    sendData("{\"mainSwitch\": 0 }", DATATYPE_STR);
                    mainSwitch.setChecked(false);
                }
            }
        });
        //初始化socket连接
        initSocket();
    }

    /**
     * 初始化Socket连接
     */
    @SuppressLint("MissingPermission")
    public void initSocket() {
        // showLoadingDialog("正在与【" + mCurDevice.getName() + "】进行连接...");
        // Looper.prepare();

        try {
            //创建Socket
            BluetoothSocket socket = mCurDevice.createRfcommSocketToServiceRecord(GlobalDef.BT_UUID);
            //启动连接线程
            socket.connect();
            mThread = new DeviceBluetoothInfoActivity.SocketThread(socket);
            mThread.start();

            Toast.makeText(mContext, "成功与【" + mCurDevice.getName() + "】建立连接", Toast.LENGTH_SHORT).show();
            // 数据发送测试
//                sendData();
            //dismissLoadingDialog();
            // 弹窗
            //showBluetoothInfo();

        } catch (IOException e) {
            Log.d(TAG, "socket connect fail");
            showToast(("连接【" + mCurDevice.getName() + "】失败"));
            e.printStackTrace();
        }

    }

    /**
     * 使用Toast展示信息
     * @param msg
     */
    public void showToast(String msg) {
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }

    /**
     * 断开连接
     */
    public void disconnect() {
        if (mThread == null || !mThread.isConnected()) {
            showToast("未存在蓝牙连接");
            return;
        }

        try {
            if (mThread != null) {
                mThread.release();
                mThread = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送数据
     *
     * @param msg      要发送的数据
     * @param sendType 发送数据的类型
     * @return 是否发送成功
     */
    public boolean sendData(String msg, int sendType) {

        if (mThread == null || !mThread.isConnected()) {
            Toast.makeText(this, "蓝牙socket未连接", Toast.LENGTH_SHORT).show();
            return false;
        }

        if (msg == null || msg.trim().equals("")) {
            Toast.makeText(this, "发送数据不能为空!", Toast.LENGTH_SHORT).show();
            return false;
        }

        try {
            byte[] bData = null;
            if (sendType == DATATYPE_STR) {
                bData = msg.getBytes();
            } else {
                bData = StringUtil.hexStringToBytes(msg);
            }

            if (bData == null) {
                Toast.makeText(this, "编辑框内的数据不符合要求!", Toast.LENGTH_SHORT).show();
                return false;
            }

            if (mThread != null) {
                mThread.writeData(bData, 0, bData.length);
//                showToast("数据发送成功");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
//            showToast("数据发送出现异常!");
            return false;
        }
        return false;
    }

    /**
     * socket线程类
     */
    class SocketThread extends Thread {
        /**
         * 蓝牙socket线程
         */
        private BluetoothSocket mSocket = null;
        /**
         * 输入流
         */
        private InputStream mIn;
        /**
         * 输出流
         */
        private OutputStream mOut;
        /**
         * 线程打开状态
         */
        private boolean isOpen = false;
        /**
         * 字节数组 10kb
         */
        private byte[] mRecBuffer = new byte[1024 * 10];
        /**
         * 流中的数据个数
         */
        private int mRecPos = 0;

        /**
         * 构造函数
         * @param socket 蓝牙socket线程
         */
        public SocketThread(BluetoothSocket socket) {
            try {
                mSocket = socket;
                mIn = mSocket.getInputStream();
                mOut = mSocket.getOutputStream();
                isOpen = true;
                Log.d(TAG, "a socket thread create");
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG, "create SocketThread fail");
            }
        }

        /**
         * 线程运行的方法
         */
        @Override
        public void run() {
            int readLen = 0;
            byte[] buffer = new byte[1024];
            try {
                while (isOpen) {
                    readLen = mIn.read(buffer);
                    if (readLen > 0) {
                        System.arraycopy(buffer, 0, mRecBuffer, mRecPos, readLen);
                        mRecPos += readLen;

                        while (true) {
                            if (mIn.available() > 0) {//若流中有数据，则读取
                                readLen = mIn.read(buffer);
                                if ((mRecPos + readLen) > mRecBuffer.length) {//超出缓冲区
                                    showToast("读取数据超出缓冲区，将已读取的数据输出：");
                                    showToast("Receive hex data = " + StringUtil.bytesToHexString(mRecBuffer, 0, mRecPos));
                                    showToast("Receive string data = " + new String(mRecBuffer, 0, mRecPos).trim());
                                    mRecPos = 0;
                                    Arrays.fill(mRecBuffer, (byte) 0x00);
                                }

                                System.arraycopy(buffer, 0, mRecBuffer, mRecPos, readLen);
                                mRecPos += readLen;
                            } else {//若流中无数据
                                if (mRecPos > 0) {//说明此时数据读取完毕，将内容输出
                                    // showToast("Receive hex data = " + StringUtil.bytesToHexString(mRecBuffer, 0, mRecPos));
                                    //showToast("Receive string data = " + new String(mRecBuffer, 0, mRecPos).trim());
                                    Log.i("socket", "Receive string data = " + new String(mRecBuffer, 0, mRecPos).trim());

                                    //更新界面数据
                                    txt_msg_bluetooth.setText(new String(mRecBuffer, 0, mRecPos).trim());
//                                    Looper.prepare();
//                                    Toast.makeText(mContext,new String(mRecBuffer, 0, mRecPos).trim(),Toast.LENGTH_SHORT).show();
//                                    Looper.loop();

                                    mRecPos = 0;
                                    Arrays.fill(mRecBuffer, (byte) 0x00);
                                }
                                break;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                release();
            }
        }

        /**
         * 是否连接成功
         *
         * @return 布尔类型 true表示连接成功
         */
        public boolean isConnected() {
            if (isOpen && mSocket != null) {
                return true;
            }
            return false;
        }

        /**
         * 释放
         */
        public void release() {
            Log.d(TAG, "A socketThread release");
            try {
                if (isOpen) {
                    showToast("与蓝牙服务端的连接已断开");
                }
                isOpen = false;

                if (mOut != null) {
                    try {
                        mOut.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    mOut = null;
                }
                if (mIn != null) {
                    try {
                        mIn.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    mIn = null;
                }
                if (mSocket != null) {
                    try {
                        mSocket.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    mSocket = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 写入数据
         * @param data 字节数组
         * @param offset 偏移值
         * @param len 数组长度
         */
        public void writeData(byte[] data, int offset, int len) {
            if (data == null || offset < 0 || len <= 0 || (len + offset) > data.length) {
                Log.e(TAG, "BT writeData params fail");
                return;
            }

            try {
                byte[] buffer = new byte[1024];
                int nPos = offset;
                while ((nPos - offset) < len) {
                    Arrays.fill(buffer, (byte) 0x00);
                    if ((len + offset - nPos) >= buffer.length) {
                        System.arraycopy(data, nPos, buffer, 0, buffer.length);
                        mOut.write(buffer);
                        nPos += buffer.length;

                    } else {
                        int last = len + offset - nPos;
                        System.arraycopy(data, nPos, buffer, 0, last);
                        mOut.write(buffer, 0, last);
                        nPos += last;
                    }
                }
                mOut.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 返回键状态监听
     *
     * @param item 菜单栏
     * @return true表示单击
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home) {
            finish();
            disconnect();
        }
        return super.onOptionsItemSelected(item);
    }
}
